/********************************************************************************
 * @file    app_mdns.c
 * @brief   mDNS服务应用逻辑处理
 * 
 * @author  nzttj
 * @date    2025-03-13
 * @version 1.0
 * 
 * Copyright (C) 2025 nzttj
 * 
 * 本软件使用 GNU 通用公共许可证 (GPL) 第 3 版授权。
 * 
 * 您可以自由使用、修改、分发本软件，但必须遵守以下条件：
 * 1. 源代码必须开放，且您修改后的代码也必须以 GPL 许可证发布。
 * 2. 发布或分发本软件时，必须附带本许可证，并提供源代码或获取源代码的方式。
 * 
 * 本软件按“原样”提供，不附带任何担保，使用风险由用户自行承担。
 * 
 ********************************************************************************/

#include "app_mdns.h"
#include "app_udp.h"

#include "mdns.h"
#include "esp_log.h"

#define MDNS_HOSTNAME       "smart-socket"
#define MDNS_INSTANCE_NAME  "Smart Socket"
#define MDNS_SERVICE_TYPE   "_iotctrl-udp"
#define MDNS_SERVICE_PROTO  "_udp"
#define MDNS_SERVICE_PORT   APP_UDP_PORT

static const char *TAG = "app_mdns";
static bool mdns_init_flag = false;

int app_mdns_init(void)
{
    if (mdns_init_flag) {
        ESP_LOGW(TAG, "mdns already initialized");
        return 0;
    }

    int ret = 0;
    ret = mdns_init();
    if (ret != 0)
    {
        ESP_LOGE(TAG, "mdns_init failed");
        return ret;
    }

    uint8_t mac[6];
    char *hostname;
    esp_read_mac(mac, ESP_MAC_WIFI_STA);
    if (-1 == asprintf(&hostname, "%s-%02x%02x%02x", MDNS_HOSTNAME, mac[3], mac[4], mac[5]))
    {
        ESP_LOGE(TAG, "asprintf failed");
        return -1;
    }

    ret = mdns_hostname_set(hostname);
    free(hostname);
    if (ret != 0)
    {
        ESP_LOGE(TAG, "mdns_hostname_set failed");
        return ret;
    }

    // 设置实例名称
    char *instance_name = NULL;
    if (-1 == asprintf(&instance_name, "%s-%02x%02x%02x", MDNS_INSTANCE_NAME, mac[3], mac[4], mac[5]))
    {
        ESP_LOGE(TAG, "asprintf failed");
        return -1;
    }
    ret = mdns_instance_name_set(instance_name);
    if (ret != 0)
    {
        free(instance_name);
        ESP_LOGE(TAG, "mdns_instance_name_set failed");
        return ret;
    }
    ret = mdns_service_add(instance_name, MDNS_SERVICE_TYPE, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0);
    if (ret != 0)
    {
        free(instance_name);
        ESP_LOGE(TAG, "mdns_service_add failed");
        return ret;
    }
    free(instance_name);
    mdns_txt_item_t serviceTxt[] = {{"board", "esp12f"}, {"version", PROJECT_VER}};
    ret = mdns_service_txt_set(MDNS_SERVICE_TYPE, MDNS_SERVICE_PROTO, serviceTxt, sizeof(serviceTxt) / sizeof(mdns_txt_item_t));
    if (ret != 0)
    {
        ESP_LOGE(TAG, "mdns_service_txt_set failed, %s", esp_err_to_name(ret));
        return ret;
    }

    mdns_init_flag = true;

    ESP_LOGI(TAG, "mdns_init success");
    return 0;
}

int app_mdns_deinit(void)
{
    if (!mdns_init_flag) {
        ESP_LOGW(TAG, "mdns not initialized");
        return 0;
    }

    mdns_free();
    mdns_init_flag = false;
    return 0;
}

